/****
留言系统前台展示留言表
****/
<template>
  <div class="form-content">
    <el-form class="form-container" ref="formRef" :model="formData"  :label-width="props.labelWidth" :label-position="props.labelPosition" :hide-required-asterisk="false">
      <el-form-item v-for="field in newFields" :key="field.id" :label="field.label" :class="field.value == ''" 
          :prop="field.required == 'true' ? field.name : ''"  :rules="field.required === 'true' && field.value == '' ? [{ required: true,  message: `请输入${field.label}`, 
          trigger: ['blur', 'change'] } ] : []" label-position="top" :style="{width:field.width + '%'}">
        <template v-if="field.type === 'classify'">
          <el-radio-group v-model="field.value">
            <el-radio v-for="option in field.options" :key="option.value" :label="option.value">
              <span class="radio-label">{{option.label}}</span>
            </el-radio>
          </el-radio-group>
        </template>
        <template v-if="field.type === 'input'">
          <el-input v-model="field.value" placeholder="请输入" :maxlength="field.openRestrict == 'true' ? field.maxLength :''" :show-word-limit="field.openRestrict" />
        </template>
        <template v-else-if="field.type === 'textarea'">
          <!-- <el-input v-model="field.value" type="textarea" placeholder="请输入" rows="4"/> -->
          <TinymceEditor
            v-model:modelValue="field.value"
            :minHeight="500"
          />
        </template>
        <template v-else-if="field.type === 'numberInput'">
          <el-input-number v-model="field.value" :min="1" :max="field.maxNumber" :precision="field.precision"/>
        </template>
        <template v-else-if="field.type === 'select'">
          <el-select v-model="field.value" placeholder="请选择">
            <el-option v-for="option in field.options" :key="option.value" :label="option.label" :value="option.value" />
          </el-select>
        </template>
        <template v-else-if="field.type === 'multiSelect'">
          <el-select v-model="field.value" multiple placeholder="请选择">
            <el-option v-for="option in field.options" :key="option.value" :label="option.label" :value="option.value" />
          </el-select>
        </template>
        <template v-else-if="field.type === 'date'">
          <el-date-picker v-model="field.value" placeholder="请选择日期" />
        </template>
        <template v-else-if="field.type === 'upload'">
          <el-upload ref="uploadRef" action="" :before-upload="handleBeforeUpload" :limit="1" :http-request="handleUpload" accept=".mp4,.docx,.pdf," >
            <el-button type="primary" @click="showFile(field)">点击上传</el-button>
          </el-upload>
        </template>
        <p class="tips">{{ field.description }}</p>
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup>
import { ref, reactive, defineProps, defineExpose, watch } from 'vue'
import TinymceEditor from "@/components/TinymceEditor.vue";
import { singleUpload, splitUpload } from '@/utils/upload'
import { ElMessage } from 'element-plus'
import { useStore } from 'vuex'

const store = useStore()
const props = defineProps({
  fields: {
    type: Array,
    default: () => []
  },
  modelValue: {
    type: Object,
    default: () => ({})
  },
  disabled: {
    type: Boolean,
    default: false
  },
  uploadAction: {
    type: String,
    default: ''
  },
  labelWidth: {
    type: String,
    default: ''
  },
  labelPosition: {
    type: String,
    default: 'top'
  }
})
const newFields = ref([...props.fields]);

modifyOption(newFields.value)

watch(() => props.fields, (newOptions) => {
  newFields.value = [...newOptions];
  modifyOption(newFields.value)
}, { deep: true });

function modifyOption(data) {
  data.forEach(item => {
    try {
      const result = JSON.parse(item.options);
      item.options = result
    } catch (e) {
      return item
    }
  });
}

const formRef = ref(null)
const formData = ref({})
const uploadRef = ref(null);
const clearFileList = () => {
  if (uploadRef.value) {
    uploadRef.value.clearFiles(); 
  }
};
// 初始化表单数据
watch(
  () => props.modelValue,
  newVal => {
    formData.value = { ...newVal }
  },
  { immediate: true }
)
const sizeLimit = ref(0)
sizeLimit.value = Number(props.sizeLimit || 100 * 1048576)
const singleActionUrl = ref(store.state.content.singleActionUrl)
const splitActionUrl = ref(store.state.content.splitActionUrl)
// 上传相关方法
const loadingFiles = reactive([])

const currentFileType = ref('')
const currentFileName = ref('')
const handleBeforeUpload = async file => {
  currentFileType.value = file.type
  currentFileName.value = file.name
  //限制文件上传大小
  const limitPass = file.size < sizeLimit.value
  if (!limitPass) {
    ElMessage({
      showClose: true,
      message: `文件大小不能超过 ${getSizeText(sizeLimit.value)}!，当前${getSizeText(file.size)}`,
      type: 'warning'
    })
    return false
  }
  loadingFiles.push(file.uid)
  return true
}
const getSizeText = size => {
  if (size > 0 && size / 1024 / 1024 < 1) {
    return (size / 1024).toFixed(2) + 'Kb'
  } else if (size / 1024 / 1024 >= 1) {
    return (size / 1024 / 1024).toFixed(2) + 'MB'
  } else {
    return size + 'b'
  }
}
const handleUploadSuccess = (fieldName, response) => {
  for (let item of newFields.value) {
    if (item.id === currentFile.value) {
      // 更改当前存入表单的值，存入文件地址
      item.value = response; 
      item.fileType = currentFileType.value;
      item.fileName = currentFileName.value;
      console.log("更改后的值",item);
      break; 
    }
  }
}
const handleUpload = async option => {
  if (option.file.size > 5 * 1024 * 1024) {
    let res = await splitUpload(option.file, splitActionUrl.value, option.onProgress, 5 * 1024 * 1024)
    handleUploadSuccess(option.file, res.url)
  } else {
    // 不切片
    let data = new FormData()
    data.append('file', option.file)
    data.append('path', 'public')
    let res = await singleUpload(data, singleActionUrl.value, option.onProgress)
    handleUploadSuccess(option.file, res.data.url)
  }
}
const currentFile = ref()
const showFile = (item) => {
  // 存入当前上传文件的表单项的id 
  currentFile.value = item.id
  console.log("item",currentFile.value);

}
// 表单验证方法
const validate = async () => {
  if (!formRef.value) return false
  return await formRef.value.validate()
}

// 重置表单
const resetFields = () => {
  if (formRef.value) {
    formRef.value.resetFields()
  }
}

// 获取表单数据
const getFormData = () => {
  return formData.value
}

defineExpose({
  validate,
  resetFields,
  getFormData,
  uploadRef,
  clearFileList
})
</script>
<style>
  .radio-label{
    margin-right: 10px;
  } 
 
  .form-content {
    /* padding: 50px 100px; */
    
    .el-form {
      max-width: 800px;
      margin: 0 auto;
      display: flex;
      flex-wrap: wrap;
      .el-form-item {
        scroll-margin-top: 20px;
        margin-bottom: 15px;
        padding-right: 10px;
        box-sizing: border-box;
        .question-content {
          padding-left: 21px;
          box-sizing: border-box;

          .question-description {
            margin-bottom: 10px;
            line-height: 14px;
            font-size: 14px;
            color: #606266;
          }
        }
        .el-form-item__label {
          font-size: 16px;
          font-weight: bold;
        }
        .el-form-item__content{
          font-size: 14px;
        }
        ::v-deep .el-form-item__error {
          margin-top: 5px;
          padding-left: 21px;
        }
      }
      ::v-deep .el-form-item:not(.is-required) .el-form-item__label {
        margin-left: 21px;
      }
      
    }
  }
  .el-form-item--label-top {
    display: block;
  }
  
  .tips{
    font-size: 12px;
    color: #777;
    line-height: 2;
  }
  ::v-deep .el-form-item__content{
    align-items: start;
    margin-right: 10px;
  }
  .el-input{
    height: max-content;
  }
  @media (max-width: 960px) {
    .form-content  .el-form  .el-form-item {
      margin-bottom: 15px;
      width: 100% !important;
      padding-right: 0;
    }
  }
</style>
